package com.mrduan.otgfilemanager.web;

import android.net.Uri;

import com.github.mjdev.libaums.fs.UsbFile;
import com.github.mjdev.libaums.fs.UsbFileInputStream;
import com.mrduan.otgfilemanager.ui.getstrong.GetStrongActivity;
import com.orhanobut.logger.Logger;

import java.io.IOException;
import java.io.InputStream;
import java.net.FileNameMap;
import java.net.URLConnection;
import java.util.Map;

import fi.iki.elonen.NanoHTTPD;

/**
 * https://blog.csdn.net/lzqzx/article/details/37694439
 * Created by duany on 2018/5/9.
 */

public class MeidaNanoHTTPD extends NanoHTTPD {
    public MeidaNanoHTTPD() throws IOException {
        super(8888);
        start(NanoHTTPD.SOCKET_READ_TIMEOUT, false);
    }


    @Override
    public Response serve(IHTTPSession session) {
        try {
            String url = Uri.decode(session.getUri());

            if (url == null) {
                return super.serve(session);
            }
            String range = null;

            Map<String, String> headers = session.getHeaders();
            for (String key : headers.keySet()) {
                // Log.e(TAG, key + ":" + headers.get(key) + ", val:" + headers.get(key));
                if ("range".equals(key)) {
                    range = headers.get(key); // 读取range header，包含要返回的媒体流位置等信息。
                }
            }


            UsbFile file = getFile(url);

            if (file != null) {

                String mimeType = getMimeType(url); //根据文件名返回mimeType： image/jpg, video/mp4, etc

                Response res = null;
                if (range == null) {

                    // 如果range为空，返回该文件的所有媒体流
                    InputStream is = new UsbFileInputStream(file);
                    res = newChunkedResponse(Response.Status.OK, mimeType, is);
                    res.addHeader("Content-Length", String.valueOf(file.getLength()));
                } else {

                    // 根据range参数，返回制定位置的媒体流

                    res = getPartialResponse(file, range, mimeType);
                }

//                Calendar cd = Calendar.getInstance();
//                cd.setTimeZone(TimeZone.getTimeZone("GMT"));
//                cd.setTimeInMillis(file.lastModified());
//                res.addHeader("Last-Modified", sGmtFrmt.format(cd.getTime()));

                return res;
            } else {
                Logger.e("file is null");
            }

            return super.serve(session);

        } catch (Exception e) {
            Logger.e("HttpServer serve:" + e);
        } finally {
            Logger.e("before return in serve");
        }
        return super.serve(session);
    }

    // 根据range中定义的范围返回媒体流
    private Response getPartialResponse(UsbFile file, String rangeHeader, String mimeType) throws IOException, IOException {
        String rangeValue = rangeHeader.trim().substring("bytes=".length());
        long fileLength = file.getLength();
        long start, end;
        if (rangeValue.startsWith("-")) {
            end = fileLength - 1;
            start = fileLength - 1
                    - Long.parseLong(rangeValue.substring("-".length()));
        } else {
            String[] range = rangeValue.split("-");
            start = Long.parseLong(range[0]);
            end = range.length > 1 ? Long.parseLong(range[1])
                    : fileLength - 1;
        }
        if (end > fileLength - 1) {
            end = fileLength - 1;
        }

// 解析range中的start，end位置

        InputStream fileInputStream;
        if (start <= end) {
            long contentLength = end - start + 1;
            fileInputStream = new UsbFileInputStream(file);
            fileInputStream.skip(start); //将媒体流跳转到start处，然后返回

            Response response = newChunkedResponse(Response.Status.PARTIAL_CONTENT, mimeType, fileInputStream);
            response.addHeader("Content-Range", "bytes " + start + "-" + end + "/" + fileLength);
            response.addHeader("Content-Length", contentLength + "");
            return response;
        } else {
            return newFixedLengthResponse(Response.Status.RANGE_NOT_SATISFIABLE, MIME_HTML, rangeHeader);
        }
    }


    public UsbFile getFile(String uri) {
//        String[] fNames = uri.split("/");

        UsbFile file = null;

        if (GetStrongActivity.root != null) {

            String[] fNames = uri.split("/");

            file = GetStrongActivity.root;

            for (int i = 1; i < fNames.length; i++) {
                String fName = fNames[i];
                if (fName.length() == 0 || fName.equals("")) {
                    continue;
                }
                if (file != null) {
                    file = getFile(file, fName);
                }
            }

            return file;
        }

        return file;
    }

    public UsbFile getFile(UsbFile parent, String fName) {

        if (parent.isDirectory()) {
            try {
                UsbFile[] files = parent.listFiles();
                for (UsbFile arg : files) {
                    if (arg.getName().equals(fName)) {
                        Logger.d("名称：" + arg.getName());
                        return arg;
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return null;
    }

    public static String getMimeType(String fileUrl) throws java.io.IOException {
        FileNameMap fileNameMap = URLConnection.getFileNameMap();
        String type = fileNameMap.getContentTypeFor(fileUrl);

        return type;
    }

}
